package com.ww.springboot.boot.util;

/**
 * 描述：
 *
 * @author wanwei
 * @since 2021-08-10 16:34
 */
public class HexUtil {

    /**
     * 指定进制转化
     *
     * @param num
     * @param hex
     * @return
     */
    public static String hexChange(Long num, int hex) {
        //正数的二进制 除2取余即可 负数的二进制 = (符号位保留)正数的二进制 取反 取补(+1)
        String ss = "";
        if (num > 0) {
            ss = getHexString(hex, num);
            return ss;
        } else {
            //转2机制再取反
            //先取反
            ss = reverse(hexChange(-num, 2));
            ss = "1" + ss.substring(1);
            //再加1
            ss = addOne(ss);
            //再将2进制转成10进制 再将十进制转成16进制
            ss = hexChange(twoToTen(ss), hex);
        }
        return ss;
    }

    public static Long twoToTen(String ss) {
        Long l = 0L;
        for (int i = 0; i < ss.length(); i++) {
            l += (long) ((ss.charAt(ss.length() - i - 1) - 48) * Math.pow(2, i));
        }
        return l;
    }


    /**
     * 获取正数二进制表达
     *
     * @param hex
     * @param num
     * @return
     */
    private static String getHexString(int hex, Long num) {
        if (num < 0) {
            num = 0 - num;
        }
        String ss = "";
        while (num > 0) {
            Long mod = num % hex;
            if (mod < 10) {
                ss = mod + ss;
            } else {
                ss = (char) (mod + 55) + ss;
            }
            num /= hex;
        }
        return ss;
    }


    public static String reverse(String str) {
        String strNew = "";
        //按32位补0
        for (int i = 1; i <= 32; i++) {
            if (str.length() < i) {
                strNew = '1' + strNew;
                continue;
            }
            if (str.charAt(str.length() - i) == '0') {
                strNew = '1' + strNew;
            } else if (str.charAt(str.length() - i) == '1') {
                strNew = '0' + strNew;
            }
        }
        return strNew;
    }

    public static String addOne(String str) {
        String strNew = "";
        Boolean isAdd = true;
        for (int i = 1; i <= str.length(); i++) {
            if (!isAdd) {
                strNew = str.charAt(str.length() - i) + strNew;
                continue;
            }
            if (str.charAt(str.length() - i) == '0') {
                strNew = '1' + strNew;
                isAdd = false;
            } else if (str.charAt(str.length() - i) == '1') {
                strNew = '0' + strNew;
                isAdd = true;
            }
        }
        return strNew;
    }
}
